到目前為止,我們實驗的環境都是三個節點,二個compute node,只有一個節點做為network node (同時也擔任controller node使用)。所以在之前要與Internet相連的實驗中,我們大多會在netwrok-controller node上進行觀查。因為只有一個network node,就一定會發生單節點失效(Single Point Failure)的問題。今天只有一個network node,如果這個node故障了,就無法連到Internet上。我們今天就來了解OpenStack如何做到network node的高可用性。
之前的packstack 安裝參數中,指定一個節點做為network node,二個節點做為compute,相對應的參數如下:
--os-network-hosts=192.168.33.10 \
--os-compute-hosts=192.168.33.20,192.168.33.30 \
為了要建立一個網路高可用的OpenStack,只要指定二個以上的節點做為network node即可,所以我們今天的改動如下:
--os-network-hosts=192.168.33.10,192.168.33.20 \
--os-compute-hosts=192.168.33.30 \
整個完整的指指如下:
packstack \
--nova-libvirt-virt-type=kvm \
--keystone-admin-passwd=password \
--os-debug-mode=y \
--provision-demo=n \
--os-neutron-ml2-type-drivers=flat,vlan \
--os-neutron-ml2-vlan-ranges=flat0:3001:4000 \
--os-neutron-ml2-tenant-network-types=' ' \
--os-neutron-ml2-mechanism-drivers=ovn \
--os-neutron-ml2-flat-networks=* \
--os-neutron-l2-agent=ovn \
--os-neutron-ovn-bridge-mappings=extnet0:br-ex,flat0:br-eth2 \
--os-neutron-ovn-bridge-interfaces=br-ex:eth0,br-eth2:eth2 \
--os-neutron-ovn-bridges-compute=br-eth2 \
--os-neutron-ovn-tunnel-if=eth1 \
--os-cinder-install=n \
--os-swift-install=n \
--os-aodh-install=n \
--os-ceilometer-install=n \
--os-horizon-install=n \
--os-controller-host=192.168.33.10 \
--os-network-hosts=192.168.33.10,192.168.33.20 \
--os-compute-hosts=192.168.33.30 \
--install-hosts=192.168.33.10,192.168.33.20,192.168.33.30
今天再照著Day-21: Router 連接External Network的步驟,透過Router將Geneve與External Network連接起來。建立出來的OpenStack Network 架構和之前的長相會是完全相同的。
openstack network create --provider-network-type geneve --provider-segment 123 n1
openstack subnet create --subnet-range 172.16.100.0/24 --network n1 n1subnet
openstack network create --provider-network-type flat --provider-physical-network extnet0 ext_n2 \
--external
# for VirtualBox
SUBNET_RANGE=10.0.2.0/24
GATEWAY=10.0.2.2
ALLOCATION_RANGE=start=10.0.2.210,end=10.0.2.220
openstack subnet create --subnet-range ${SUBNET_RANGE} --network ext_n2 extsubnet \
--no-dhcp \
--gateway ${GATEWAY} \
--allocation-pool ${ALLOCATION_RANGE}
IMAGE_ID=$(openstack image show cirros --format json | jq -r .id)
openstack server create --nic net-id=n1,v4-fixed-ip=172.16.100.10 --flavor m1.nano --image $IMAGE_ID vm_1
openstack router create r
openstack router add subnet r n1subnet
openstack router set r --external-gateway ext_n2
接著,來看一下於logical router上與External Network相連的port,在這裡為lrp-1107c2
的gateway-chassis屬性,有二個chassis id,而之前只有一個chassis id。大家可以回去和Day-21: Router 連接External Network比較看看。
查看North Bound DB的 gateway chassis 與 logical router port的關係
因為有二個Network node 都可做為對外的節點,所以可以看到gateway_chassis有二個,這二個chassis分別對到二個Network node上的chassis. 且每個chassis有priority,會優先使用數值高的做為gateway
vn-nbctl list gateway_chassis | abbrev
uuid : f6548a
hassis_name : "a807ec"
xternal_ids : {}
ame : lrp-1107c2_a807ec
ptions : {}
riority : 2
uuid : 33d2ff
hassis_name : "1d03fd"
xternal_ids : {}
ame : lrp-1107c2_1d03fd
ptions : {}
riority : 1
``
透過查詢NB DB,可以知道logical router port會使用那些chassis. 這邊看到lrp-1107c2
會使用[1d03fd a807ec]
這二個chassis.
ovn-nbctl show | abbrev
...
router f9b418 (neutron-cc5b1f) (aka rr)
port lrp-1107c2
mac: "fa:16:3e:5e:01:d1"
networks: ["192.168.0.42/24"]
gateway chassis: [1d03fd a807ec]
ovn-nbctl --columns name,gateway_chassis list logical_router_port
...
name : lrp-1107c254-2e3c-477d-bbd3-2511104b42c8
gateway_chassis : [1d03fdeb-838c-4c1e-a6aa-1b6b55320e13, a807ec86-77ce-4722-9deb-f020f4eba94e]
再一次和Day-21: Router 連接External Network相比,因為今天的環境有二個network node,所以可以看到有br-ex的節點有二個,而上述在North bound 與South bound DB查到的logical router會使用的chassis,剛好就是對應至這二個network node,這就代表封包會由這二個node的其中一個上網,至於會使用那一個network node呢? 讓我們來看一下。
查看South BoundDB ,可以查看router實際是綁定到那一個chassis,代表著traffic會透過綁定的chassis對外
lrp-1107c2
透過 Port_Binding cr-lrp-1107c2
和Chassis a807ec
做綁定,所以router的traffic會由 192.168.33.10出去
ovn-sbctl show | abbrev
hassis "1d03fd"
hostname: compute-01.home.lab
Encap geneve
ip: "192.168.33.30"
options: {csum="true"}
Port_Binding "14a6a4"
hassis "3c2e27"
hostname: network.home.lab
Encap geneve
ip: "192.168.33.20"
options: {csum="true"}
hassis "a807ec"
hostname: network-controller.home.lab
Encap geneve
ip: "192.168.33.10"
options: {csum="true"}
Port_Binding cr-lrp-1107c2
``
下一步,就讓我們在二個network node上抓封包,驗證一下是不是這的如我們所說的,由192.168.33.10 出去。
在compute-01 上抓geneve tunnel 封包,對外的traffic經由tunnel往192.168.33.10
,(因為目前logical router port是綁定在192.168.33.10的chassis上)
tcpdump -vvneei eth1 'udp port 6081'
11:16:46.654492 da:ac:a9:da:bc:69 > f6:68:77:07:9b:48, ethertype IPv4 (0x0800), length 156: (tos 0x0, ttl 64, id 37979, offset 0, flags [DF], proto UDP (17), length 142)
192.168.33.30.20454 > 192.168.33.10.geneve: [bad udp cksum 0x82d0 -> 0x78c6!] Geneve, Flags [C], vni 0x3, proto TEB (0x6558), options [class Open Virtual Networking (OVN) (0x102) type 0x80(C) len 8 data 00030002]
fa:16:3e:5e:01:d1 > d6:82:25:f4:71:e9, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 63, id 29561, offset 0, flags [DF], proto ICMP (1), length 84)
172.16.100.10 > 8.8.8.8: ICMP echo request, id 32437, seq 1, length 64
11:16:46.659561 f6:68:77:07:9b:48 > da:ac:a9:da:bc:69, ethertype IPv4 (0x0800), length 156: (tos 0x0, ttl 64, id 47717, offset 0, flags [DF], proto UDP (17), length 142)
192.168.33.10.2371 > 192.168.33.30.geneve: [bad udp cksum 0x82d0 -> 0x6f26!] Geneve, Flags [C], vni 0x1, proto TEB (0x6558), options [class Open Virtual Networking (OVN) (0x102) type 0x80(C) len 8 data 00030002]
fa:16:3e:c5:31:1e > fa:16:3e:22:58:b6, ethertype IPv4 (0x0800), length 98: (tos 0x60, ttl 112, id 0, offset 0, flags [none], proto ICMP (1), length 84)
8.8.8.8 > 172.16.100.10: ICMP echo reply, id 32437, seq 1, length 64
在對外的eth0上抓封包,和前幾天討論的說法一致,先做過SNAT轉成對外的IP後,經由VirtualBox的NAT對外傳送
tcpdump -i eth0 icmp
11:16:46.654504 IP 10.0.2.211 > dns.google: ICMP echo request, id 32437, seq 1, length 64
11:16:46.659384 IP dns.google > 10.0.2.211: ICMP echo reply, id 32437, seq 1, length 64
若某個Chassis 故障,router port 會重新綁到別的chassis,以達到HA,我們修改192.168.33.10的iptables,讓它阻擋geneve protocl的封包,模擬network node 故障。來看看會發生什麼事情吧。
#把drop udp/6081 設為第一個rule, drop 所有geneve packet
sudo iptables -I INPUT 1 -p udp --dport 6081 -j DROP
一旦把阻擋geneve protocl的封包,可以看到logical router port綁定到另一個network-controller node上,再來,就讓大家自己去這個節點上抓封包驗證看看囉。
$ovn-sbctl show | abbrev
Chassis "1d03fd"
hostname: compute-01.home.lab
Encap geneve
ip: "192.168.33.30"
options: {csum="true"}
Port_Binding "14a6a4"
Chassis "3c2e27"
hostname: network.home.lab
Encap geneve
ip: "192.168.33.20"
options: {csum="true"}
Port_Binding cr-lrp-1107c2
Chassis "a807ec"
hostname: network-controller.home.lab
Encap geneve
ip: "192.168.33.10"
options: {csum="true"}